var basicConfig = function() {
    return {
        /**
         * 标准检验项数据处理
         * @param {Object} data 接口数据
         * @param {String} keyName 主键id
         * @return {Object} 返回子表子子表数据  
         */
        initConfig: function({
            ds1,
            ds2,
            ds3,
            ds4
        }, keyName, childKeyName) {
            const inspections = [];
            const FQCDetail = [];

            ds3.forEach(item => {
                let parsedFResult = parseInt(item.FResult);
                if (![0, 1, 99].includes(parsedFResult)) parsedFResult = 99;

                const ins = {
                    name: item.YPMC,
                    result: parsedFResult,
                    FRemarks: item.FRemarks || '',
                    insID: item[keyName],
                    ...item,
                    FQCItems: []
                };

                // 找出对应子子表项
                const ds2Children = ds4.filter(child => child[keyName] === ins.insID);
                ds2Children.forEach(child => {
                    let childFResult = parseInt(child.FResult);
                    if (![0, 1, 99].includes(childFResult)) childFResult = 99;

                    let obj = {
                        insDeID: child[childKeyName],
                        FQCItemID: child.LabTestPlanDeDeID,
                        value: `${child.JYJG1 || ''}`,
                        result: childFResult,
                        Benchmark: child.ApplianceTypeName || '',
                        IsLaboratory: child.IsLaboratory || false,
                        ...child
                    };

                    if (child.PoorWork || child.PoorNormally) {
                        obj.minNum = child.PoorNormally;
                        obj.maxNum = child.PoorWork;
                        obj.Type = 1;
                    } else {
                        obj.JYBZ = child.JYBZ;
                        obj.Type = 2;
                    }

                    // 新增：组合下极限/标准值/上极限显示
                    const minVal = obj.minNum ?? '-';
                    const stdVal = obj.JYBZ ?? '-';
                    const maxVal = obj.maxNum ?? '-';
                    obj.displayLimit = `${minVal} / ${stdVal} / ${maxVal}`;

                    ins.FQCItems.push(obj);
                });

                inspections.push(ins);
            });

            // 分类表
            ds1.forEach(item => {
                FQCDetail.push({
                    ItemID: item.LabTestProjectTypeID,
                    ItemName: item.LabTestProjectTypeName,
                    UpID: item.UpID,
                    Type: 0,
                    ...item
                });
            });

            // 检验项目表
            ds2.forEach(item => {
                const obj = {
                    ItemID: item.LabTestProductItemDeID,
                    ItemName: item.LabTestProjectName,
                    UpID: item.UpID,
                    Benchmark: item.ApplianceTypeName,
                    result: item.FResult,
                    ...item
                };

                if (item.PoorWork || item.PoorNormally) {
                    obj.minNum = item.PoorNormally;
                    obj.maxNum = item.PoorWork;
                    obj.Type = 1;
                } else {
                    obj.JYBZ = item.JYBZ;
                    obj.Type = 2;
                }

                // 新增：组合下极限/标准值/上极限显示
                const minVal = obj.minNum ?? '-';
                const stdVal = obj.JYBZ ?? '-';
                const maxVal = obj.maxNum ?? '-';
                obj.displayLimit = `${minVal} / ${stdVal} / ${maxVal}`;

                FQCDetail.push(obj);
            });

            return {
                inspections,
                FQCDetail
            };
        },
        initPageStr() {
            // 1. 递归生成表头（返回列计数和叶子列信息）
            // 递归生成表头（带路径循环检测，避免 UpID === ItemID 或更复杂的环）
            function buildTitleHeader(data, parentID, level, allCellData, startCol, leafItems, visited =
                new Set()) {
                let colIndex = startCol;

                for (const item of data) {
                    if (item.UpID !== parentID) continue;

                    // 如果当前路径上已经出现过这个 ItemID（自引用或环），把它当作叶子处理，避免递归
                    if (visited.has(item.ItemID)) {
                        // 作为叶子节点处理
                        allCellData.push(createMergedCell(level, colIndex, 1, item.ItemName));
                        allCellData.push(createMergedCell(level + 1, colIndex, 1, item.displayLimit, 6));
                        item.c = colIndex;
                        leafItems.push(item);
                        colIndex++;
                        continue;
                    }

                    // 正常查找子节点（不需要在过滤时排除 self，因为 visited 已经保护了）
                    const children = data.filter(c => c.UpID === item.ItemID);

                    if (children.length > 0) {
                        const childStartCol = colIndex;
                        // 传入新的 visited 副本，标记当前节点已访问
                        const nextVisited = new Set(visited);
                        nextVisited.add(item.ItemID);

                        const nextIndex = buildTitleHeader(data, item.ItemID, level + 1, allCellData, colIndex,
                            leafItems, nextVisited);
                        const colSpan = nextIndex - childStartCol;

                        // 当前节点作为分组头（跨 colSpan 列）
                        allCellData.push(createMergedCell(level, childStartCol, colSpan, item.ItemName));
                        colIndex = nextIndex;
                    } else {
                        // 叶子节点
                        allCellData.push(createMergedCell(level, colIndex, 1, item.ItemName));
                        allCellData.push(createMergedCell(level + 1, colIndex, 1, item.displayLimit, 6));
                        item.c = colIndex;
                        leafItems.push(item);
                        colIndex++;
                    }
                }

                return colIndex;
            }


            // 工具：生成合并单元格
            function createMergedCell(row, col, colSpan, value, fs = 9) {
                return {
                    r: row,
                    c: col,
                    v: {
                        v: value,
                        m: value,
                        ff: 1,
                        fc: "#333",
                        bl: 1,
                        fs: fs,
                        ht: 0,
                        vt: 0,
                        tb: 2,
                        mc: {
                            r: row,
                            c: col,
                            rs: 1,
                            cs: colSpan
                        }
                    }
                };
            }

            // 工具：生成普通单元格
            function createCell(r, c, value, color = "#333", bold = 0) {
                return {
                    r,
                    c,
                    v: {
                        v: value,
                        m: value,
                        ff: 1,
                        fc: color,
                        bl: bold,
                        fs: 9,
                        ht: 0,
                        vt: 0,
                        tb: 2
                    }
                };
            }

            // 2. 主函数
            function getPageData() {
                const headerTitles = vm.originData.FQCDetail;
                const headerLevel = vm.getTreeDepth(headerTitles);
                vm.headerLevel = headerLevel;

                const allCellData = [];
                const dataVerfications = {};
                vm.editCells = [];

                // 第一列：样品名称
                allCellData.push({
                    r: 0,
                    c: 0,
                    v: {
                        v: '样品名称',
                        m: '样品名称',
                        ff: 1,
                        fc: '#333',
                        bl: 1,
                        fs: 9,
                        ht: 0,
                        vt: 0,
                        tb: 2,
                        mc: {
                            r: 0,
                            c: 0,
                            rs: headerLevel + 1,
                            cs: 1
                        }
                    }
                });

                // 生成表头 & 叶子列信息
                const leafItems = [];

                const lastCol = buildTitleHeader(headerTitles, 0, 0, allCellData, 1, leafItems); // 从第1列开始

                // 遍历样品行
                const inspections = vm.originData.inspections || [];
                inspections.forEach((inspection, rowIdx) => {
                    const rowIndex = headerLevel + 1 + rowIdx;
                    // 样品名称
                    allCellData.push(createCell(rowIndex, 0, inspection.name));

                    // 构建检验值Map
                    let itemMap = new Map();
                    inspection.FQCItems.forEach(fqc => {
                        itemMap.set(fqc.FQCItemID, fqc)
                    });
                    // 填充叶子列
                    leafItems.forEach(item => {
                        const fqc = itemMap.get(item.LabTestPlanDeDeID);
                        let val = '';
                        let color = '#333';

                        if (fqc) {
                            val = fqc.value;

                            color = fqc.result == 1 ? '#07d348' : fqc.result == 0 ? '#f00' :
                                '#a8a8a8';

                            fqc.r = rowIndex;
                            fqc.c = item.c; // 这里可以直接使用item.c，因为原始对象已添加c属性
                            vm.editCells.push({
                                ...fqc
                            });
                        }
                        allCellData.push(createCell(rowIndex, item.c, val, color));
                    });
                });

                // 检验结果行
                const resultRowIndex = headerLevel + 1 + inspections.length;
                allCellData.push(createCell(resultRowIndex, 0, '检验结果', '#333', 1));

                leafItems.forEach(item => {
                    let text = '待检';
                    let color = '#a8a8a8';
                    if (item.FResult === 1) {
                        text = '合格';
                        color = '#07d348';
                    } else if (item.FResult === 0) {
                        text = '不合格';
                        color = '#f00';
                    }
                    allCellData.push(createCell(resultRowIndex, item.c, text, color));
                });

                // 渲染
                const rowNums = headerLevel + 1 + inspections.length + 1;
                const colNums = lastCol;
                vm.ExcleInit(rowNums, colNums, allCellData, dataVerfications);
            }
            getPageData();
        },
        /**
         * 获取报告数据
         */
        GetPopupInfoByDevice(str) { // 测试获取设备报告
            vm.tableData_Report = [];
            if (str == "光谱仪") {

                APP.jqueryAjax("getReportDataByID", {
                    TourInspectionDeDeID: ""
                }, function(ret) {

                    if (ret.status == 200) {
                        let data = JSON.parse(ret.data.ds[0]["testReportData"]);

                        vm.tableData_Report = data;

                        vm.tableData_Report_radio = 0;
                        let ReportData = data[vm.tableData_Report_radio];
                        Object.assign(vm.popup_ReportData, ReportData);

                        // 每次打开列表，重置预览窗口的检验结果值
                        vm.rowDeviceForm.result = 1;
                        // 打开报告列表弹层
                        vm.showTableData_Report_popup = true;
                    }
                }, function(err) {

                })

            } else if (str == "三坐标") {
                APP.jqueryAjax('getReportDataByID_1', {
                    TourInspectionDeDeID: '',
                }, function(ret) {
                    if (ret.status == 200) {

                        let data = JSON.parse(ret.data.ds[0]["testReportValue"]);
                        vm.tableData_Report = data;

                        vm.tableData_Report_radio = 0;
                        let ReportData = data[vm.tableData_Report_radio];
                        Object.assign(vm.popup_ReportData, ReportData);

                        // 每次打开列表，重置预览窗口的检验结果值
                        vm.rowDeviceForm.result = 1;
                        // 打开报告列表弹层
                        vm.showTableData_Report_popup = true;
                    }
                })

            } else if (str == "影像测量仪") {
                let data = [{
                    index: 0
                }];
                vm.tableData_Report = data;

                vm.tableData_Report_radio = 0;
                let ReportData = data[vm.tableData_Report_radio];
                Object.assign(vm.popup_ReportData, ReportData);

                // 每次打开列表，重置预览窗口的检验结果值
                vm.rowDeviceForm.result = 1;
                // 打开报告列表弹层
                vm.showTableData_Report_popup = true;
            }

        },
        /**
         * 查看当前报告弹层
         */
        ViewPopupInfoByDevice(str, data) {

            if (str == "光谱仪") {

                // 模拟数据
                if (!data) {
                    data =
                        "{\"C≤0.08\":\"0.05\", \"Si≤1.0\":\"0.33\",\"Mn≤2.0\":\"0.7\",\"S≤0.03\":\"0.004\", \"P≤0.045\":\"0.031\", \"Cr 18.0-20.0\":\"18.35\", \"Ni 8.0-12.0\":\"8.08\", \"Ti\":\"\"}"
                }


                let ReportData = JSON.parse(data);
                Object.assign(vm.popup_ReportData, ReportData);
                vm.showRowInfoByDevice = true;

            } else if (str == "三坐标") {
                // 三坐标报告，打开 luckysheet 表格展示

                vm.showRowInfoByDevice = true;

                setTimeout(() => {

                    let heightBox = $(".reportBox").outerHeight() - $(".popup_nav").outerHeight() - $(
                        ".popup_result").outerHeight() - $(".btnBox").outerHeight() - 20;

                    vm.report_frame_height = heightBox;
                    vm.openPopupIframe = true;
                    // $(".report_iframe").css({
                    //  "height": heightBox + "px"
                    // })
                }, 50)

            } else if (str == "影像测量仪") {

                vm.showRowInfoByDevice = true;

                setTimeout(() => {

                    let heightBox = $(".reportBox").outerHeight() - $(".popup_nav").outerHeight() - $(
                        ".popup_result").outerHeight() - $(".btnBox").outerHeight() - 20;

                    vm.report_frame_height = heightBox;
                    vm.openPopupIframe = true;
                }, 50)

            }


        },
        /**
         * 确认报告按钮
         */
        SubmitPopupInfoByDevice(str) {

            if (str == "光谱仪") {
                // 报告类型实测值通过 ok、ng 区分是否合格

                let text = vm.rowDeviceForm.result == 1 ? "ok" : "ng";
                vm.setRange(text, true);
                // 关闭列表弹层
                vm.showTableData_Report_popup = false;

                // 关闭详情弹层
                vm.showRowInfoByDevice = false;
            } else if (str == "三坐标") {
                // 报告类型实测值通过 ok、ng 区分是否合格

                // let text = vm.rowDeviceForm.result == 1 ? "ok" : "ng";
                // vm.setRange(text, true);

                // 不再使用ok、ng，需要把实测值回填到表格中去

                // 1、获取该样品下的检验项


                let choiceRowCellIndex = vm.editRange[0].row_focus - vm.headerLevel - 1;


                let filterLabType = vm.originData.FQCDetail.filter(item => item.Type != 0);

                // 从报告数据中过滤出符合这两个检验项的数据
                let testReportValue = window.frames[0].vm.reportInfo;

                // 先提取A中所有的name到Set中
                const aNames = new Set(filterLabType.map(item => item.ItemName));

                // 过滤B数组
                const filteredB = testReportValue.filter(item => aNames.has(item.name));


                vm.originData.inspections[choiceRowCellIndex]['FQCItems'].forEach((item, index) => {
                    // item.LabTestProjectName

                    let IsWhere = vm.indexToCell([item.r, item.c]);

                    let getCellInfo = filteredB.filter(row => row.name == item.LabTestProjectName)[0];



                    const data = [
                        [{
                            "m": getCellInfo.measuredValue, // 显示值
                            "v": getCellInfo.measuredValue, // 原始值
                            "ht": 0, // 水平对齐 0 居中、1 左、2右    
                            "vt": 0, // 垂直对齐 0 中间、1 上、2下
                            "tb": 2, // 文本换行 0 截断、1溢出、2 自动换行
                        }]
                    ];
                    basicConfig.AssignmentFunByLab({
                        data,
                        value: getCellInfo.measuredValue,
                        IsWhere,
                        p_index: index
                    })
                    // vm.AssignmentFun(data, getCellInfo.measuredValue)




                });




                // 关闭列表弹层
                vm.showTableData_Report_popup = false;

                // 关闭详情弹层
                vm.showRowInfoByDevice = false;
            } else if (str == "影像测量仪") {
                // 报告类型实测值通过 ok、ng 区分是否合格

                let text = vm.rowDeviceForm.result == 1 ? "ok" : "ng";
                vm.setRange(text, true);
                // 关闭列表弹层
                vm.showTableData_Report_popup = false;

                // 关闭详情弹层
                vm.showRowInfoByDevice = false;
            }
        },
        AssignmentFunByLab({
            data,
            value,
            IsWhere,
            p_index
        }) {
            luckysheet.setRangeValue(data, {
                range: IsWhere + ':' + IsWhere
            })

            let CellWhere = vm.cellToIndex(IsWhere);
            let TheIndex = null;
            // 将单元格位置信息与数据进行匹配，替换所在单元格的value值
            vm.originData.inspections.forEach((item, index) => {
                item.FQCItems.forEach(ReItem => {
                    // 只处理目标单元格，提前跳出减少无效计算
                    if (ReItem.r !== CellWhere[0] || ReItem.c !== CellWhere[1]) {
                        return;
                    }

                    TheIndex = index;
                    ReItem.value = value;

                    // 提前计算数值，避免重复转换，提升性能
                    const keyValue = +vm.NumberMapBack(value) || 0;
                    let effectiveMax, effectiveMin;

                    // 处理有效最大值（优先maxNum，否则用JYBZ补充）
                    if (ReItem.maxNum || ReItem.maxNum === 0) {
                        effectiveMax = +ReItem.maxNum;
                    } else if (ReItem.JYBZ || ReItem.JYBZ === 0) {
                        effectiveMax = +ReItem.JYBZ;
                    }

                    // 处理有效最小值（优先minNum，否则用JYBZ补充）
                    if (ReItem.minNum || ReItem.minNum === 0) {
                        effectiveMin = +ReItem.minNum;
                    } else if (ReItem.JYBZ || ReItem.JYBZ === 0) {
                        effectiveMin = +ReItem.JYBZ;
                    }

                    // 根据有效边界计算结果
                    if (effectiveMax !== undefined && effectiveMin !== undefined) {
                        // 同时存在max和min（包括JYBZ补充的情况）
                        ReItem.result = (keyValue >= effectiveMin && keyValue <= effectiveMax) ? 1 :
                            0;
                    } else if (effectiveMax !== undefined) {
                        // 只存在max（包括JYBZ补充的情况）
                        ReItem.result = keyValue < effectiveMax ? 1 : 0;
                    } else if (effectiveMin !== undefined) {
                        // 只存在min（包括JYBZ补充的情况）
                        ReItem.result = keyValue > effectiveMin ? 1 : 0;
                    } else {
                        // 无边界条件，仅根据检验标准判断
                        if (!ReItem.value) {
                            ReItem.result = 99;
                        } else {
                            const lowerValue = ReItem.value.toLowerCase();
                            ReItem.result = lowerValue === 'ok' ? 1 : (lowerValue === 'ng' ? 0 :
                                99);
                        }
                    }
                });
            });

            // vm.originData.inspections.forEach((item, index) => {
            //  if (TheIndex == index) {
            //      let HasNotResult = item.FQCItems.some(ReItem => {
            //          return ReItem.result == 2
            //      })
            //      if (HasNotResult) {
            //          item.result = 2
            //      } else {
            //          item.result = 1
            //      }
            //  }
            // });



            let resultSum = {
                ok: 0,
                ng: 0,
                wait: 0
            }


            for (let i = 0; i < vm.originData.inspections.length; i++) {
                let row = vm.originData.inspections[i];
                switch (row.FQCItems[p_index].result) {
                    case 99:
                        resultSum.wait += 1;
                        break;
                    case 1:
                        resultSum.ok += 1;
                        break;
                    case 0:
                        resultSum.ng += 1;
                        break;
                    default:
                        break;
                }
            };


            // 只有检验项所有检验完，才会触发检验结果变更
            if (resultSum.wait == 0) {
                // 
                let resRange = {
                    r: vm.headerLevel + vm.originData.inspections.length + 1,
                    c: CellWhere[1]
                }
                // 拒收数
                let RejectionNum = vm.originData.mainData.RejectionNum;
                // 不合格数小于等于拒收数，判定为合格
                let result = 99;
                if (resultSum.ng <= RejectionNum) {
                    result = 1;
                } else {
                    result = 0;
                };



                let restleText = result == 1 ? '合格' : result == 0 ? '不合格' : '待检验';
                let restleTextColor = result == 1 ? "#07d348" : result == 0 ? "#f00" : "#a8a8a8"
                const NewData = [
                    [{
                        "m": restleText, // 显示值
                        "v": restleText, // 原始值
                        "ht": 1, // 水平对齐 0 居中、1 左、2右    
                        "vt": 0, // 垂直对齐 0 中间、1 上、2下
                        "tb": 2, // 文本换行 0 截断、1溢出、2 自动换行 
                        "fc": restleTextColor
                    }]
                ];

                //回写单元格
                let IsResWhere = vm.indexToCell([resRange.r, resRange.c])

                luckysheet.setRangeValue(NewData, {
                    range: IsResWhere + ':' + IsResWhere
                });

                for (let i = 0; i < vm.originData.FQCDetail.length; i++) {


                    if (vm.originData.FQCDetail[i].c == resRange.c) {
                        vm.originData.FQCDetail[i]['result'] = result;
                        break;
                    }
                };



                luckysheet.setDataVerification({
                    type: 'checkbox',
                    type2: null,
                    value1: '合格',
                    value2: '不合格',
                    checked: result == 1 ? true : false
                }, {
                    range: IsResWhere
                });

            }


        },

        submitKeyword() { // 点击输入框右侧确认按钮
            if (vm.ChoiceCellData.IsLaboratory) {
                $('#autoInput').val('');
                return
            }
            vm.InputFocus = 'none';
            let text = vm.NumberMapBack($('#autoInput').val());


            const NewData = [
                [{
                    "m": text, // 显示值
                    "v": text, // 原始值
                    "ht": 0, // 水平对齐 0 居中、1 左、2右    
                    "vt": 0, // 垂直对齐 0 中间、1 上、2下
                    "tb": 2, // 文本换行 0 截断、1溢出、2 自动换行
                }]
            ];



            let ranged = {
                r: vm.editRange[0].row_focus,
                c: vm.editRange[0].column_focus,
            };
            // 转换单元格坐标格式
            let IsWhere = vm.indexToCell([ranged.r, ranged.c]);
            //回写单元格
            luckysheet.setRangeValue(NewData, {
                range: IsWhere + ':' + IsWhere
            });

            var TheIndex = null;

            // 将单元格位置信息与数据进行匹配，替换所在单元格的value值
            // 备注信息，是在子子表上体现的，意味着是第一层级的数据
            // 1、确定选中项是否是备注单元格
            if (ranged.c == vm.RemarkIndex.c) {
                // 获取选中样品的索引
                let ListIndex = ranged.r - vm.RemarkIndex.r - 1;
                // 修改指定索引下的备注字段
                vm.originData.inspections[ListIndex].FRemarks = vm.NumberMapBack($('#autoInput').val());
            } else {
                // 将单元格位置信息与数据进行匹配，替换所在单元格的value值
                // const inputVal = $('#autoInput').val();
                // const mappedValue = vm.NumberMapBack(inputVal);
                const mappedValue = text;

                const lowerValue = String(mappedValue).toLowerCase();

                for (let index = 0; index < vm.originData.inspections.length; index++) {
                    const item = vm.originData.inspections[index];

                    for (const ReItem of item.FQCItems) {
                        if (ReItem.r === ranged.r && ReItem.c === ranged.c) {
                            TheIndex = index;
                            ReItem.value = mappedValue;
                            // 提前处理值转换，避免重复计算
                            const keyValue = Number(mappedValue) || 0;
                            const lowerValue = String(mappedValue).toLowerCase(); // 统一转为小写处理

                            // 处理边界值，考虑JYBZ作为补充
                            let effectiveMin = !isNaN(Number(ReItem.minNum)) ? Number(ReItem.minNum) : undefined;
                            let effectiveMax = !isNaN(Number(ReItem.maxNum)) ? Number(ReItem.maxNum) : undefined;
                            const jybzValue = !isNaN(Number(ReItem.JYBZ)) ? Number(ReItem.JYBZ) : undefined;

                            // 当min或max不存在时，使用JYBZ作为补充边界
                            if (effectiveMin === undefined && jybzValue !== undefined) {
                                effectiveMin = jybzValue;
                            }
                            if (effectiveMax === undefined && jybzValue !== undefined) {
                                effectiveMax = jybzValue;
                            }

                            // 根据有效边界计算结果
                            if (effectiveMin !== undefined && effectiveMax !== undefined) {
                                // 同时存在上下限（包括JYBZ补充的情况）
                                ReItem.result = keyValue >= effectiveMin && keyValue <= effectiveMax ? 1 : 0;
                            } else if (effectiveMax !== undefined) {
                                // 只有上限（包括JYBZ作为上限的情况）
                                ReItem.result = keyValue < effectiveMax ? 1 : 0;
                            } else if (effectiveMin !== undefined) {
                                // 只有下限（包括JYBZ作为下限的情况）
                                ReItem.result = keyValue > effectiveMin ? 1 : 0;
                            } else {
                                // 无边界条件，仅根据检验标准文本判断
                                if (lowerValue === 'ok') {
                                    ReItem.result = 1;
                                } else if (lowerValue === 'ng') {
                                    ReItem.result = 0;
                                } else {
                                    ReItem.result = 99; // 空值或其他情况
                                }
                            }


                            // 自动切换到下一个单元格
                            if (!vm.showEditWindow && vm.allowToNext) {
                                vm.setRange(mappedValue);
                            }

                            // 找到目标后即可结束两个循环
                            break;
                            // return;
                        }
                    }
                };


                // 更改行的检验结果
                vm.ChangeRowResult(ranged)
                // vm.ChangeRowResult(ranged.r, TheIndex)
            }
            vm.showEditWindow = false;


        },
    }
}()